#ifndef FINANCEMANAGE_H_INCLUDED
#define FINANCEMANAGE_H_INCLUDED
#include <vector>
#include <string>
#include <fstream>
#include <istream>
#include <ostream>
#include <cstdio>
#include <Finance.h>
#include <windows.h>
#include <functional>
#include <algorithm>

class FinanceManage
{
public:
        vector<Finance> allFinances;
        string savePath;
        FinanceManage(string _savePath)
        {
                savePath = _savePath;
                allFinances.reserve(100000);
                load();
        }
        void add(Finance * finance)
        {
                allFinances.push_back(*finance);
                save();
        }

        /**
          * 删除指定下标元素
          * 会改变vector中元素的储存顺序
          */
        bool rm(int index)
        {
                int length = allFinances.size();
                bool flag = false;
                if (index < length && index >= 0)
                {
                        //Finance temFinance=allFinances[index];
                        allFinances[index] = allFinances[length - 1];
                        allFinances.pop_back();
                        save();
                        flag = true;
                }
                return flag;

        }

        void save()
        {

                string filePath = savePath;
                ofstream fout(filePath.c_str(), ios_base::out );
                if (!fout.is_open())
                {
                        cerr << "无法打开" << filePath << endl;
                        exit(EXIT_FAILURE);
                }
                int length = allFinances.size();
                fout << length << endl;
                for (int i = 0; i < length; i++)
                {
                        fout << allFinances[i].amount << endl;
                        fout << allFinances[i].applicant << endl;
                        fout << allFinances[i].date << endl;
                        fout << allFinances[i].description << endl;
                        fout << allFinances[i].purpose << endl;
                        fout << allFinances[i].type << endl;
                }
                fout.flush();
                fout.close();

        }

        void load()
        {
                string ch;
                Finance * temFinance;
                allFinances.clear(); //删除所有元素
                string filePath = savePath;
                ifstream fin;
                fin.open(filePath.c_str(), ios_base::in);
                if (fin.is_open())
                {
                        int length = 0;
                        fin >> length;
                        getline(fin, ch); //吃掉回车
                        for (int i = 0; i < length; i++)
                        {
                                temFinance = new Finance();
                                fin >> temFinance->amount;
                                getline(fin, ch);//吃掉回车
                                getline(fin, temFinance->applicant);
                                getline(fin, temFinance->date);
                                getline(fin, temFinance->description);
                                getline(fin, temFinance->purpose);
                                fin >> temFinance->type;
                                getline(fin, ch); //吃掉回车
                                allFinances.push_back(*temFinance);
                        }

                        fin.close();
                }
                sort(allFinances.begin(), allFinances.end(), [&](Finance x, Finance y)
                {
                        return x.date > y.date;
                });
        }

        void printAllFinance4Test()
        {
                int length = allFinances.size();
                for (int i = 0; i < length; i++)
                {
                        cout << "type = " << allFinances[i].type;
                        cout << " amount = " << allFinances[i].amount;
                        cout << " date = " << allFinances[i].date;
                        cout << " description = " << allFinances[i].description;
                        cout << " applicant = " << allFinances[i].applicant;
                        cout << " purpose  = " << allFinances[i].purpose;
                        cout << endl;
                }

        }
        /**
         返回数量
        */
        int printAllFinanceFormal()
        {
                HANDLE handle;
                handle = GetStdHandle(STD_OUTPUT_HANDLE);
                int length = allFinances.size();
                for (int i = 0; i < length; i++)
                {
                        cout << " index:" << i << "\t类型：";
                        if (allFinances[i].type == 1)
                        {
                                SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
                                cout << " 收入";
                                SetConsoleTextAttribute(handle, 0x07);
                        }
                        else
                        {
                                SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
                                cout << " 支出";
                                SetConsoleTextAttribute(handle, 0x07);
                        }
                        cout << " 数量: " << allFinances[i].amount;
                        cout << " 元   \t 用途: ";
                        if (allFinances[i].purpose == "")
                        {
                                cout << "无";
                        }
                        else
                        {
                                cout << allFinances[i].purpose;
                        }
                        cout << "\t " << (allFinances[i].type == -1 ? "使用者  " : "相关人员") << ": " << allFinances[i].applicant;
                        cout << "\n\t 描述: " << allFinances[i].description;
                        cout << "\n\t 日期: " << allFinances[i].date;
                        cout << "\n---------\n";

                }
                return allFinances.size();

        }

        int printSingleFinance(Finance * f,string status="")
        {
                cout << " 数量: " << f->amount;
                cout << " 用途: ";
                if (f->purpose == "")
                {
                        cout << "无";
                }
                else
                {
                        cout << f->purpose;
                }
                cout << "\t " << (f->type == -1 ? "使用者  " : "相关人员") << ": " << f->applicant;
                cout << "\n 描述: " << f->description;
                cout << "\n 日期: " << f->date<<"\t";
                if(status!=""){
                        cout<<"状态：";
                        if(status=="wait"){
                                cout<<"待处理";
                        }
                        if(status=="accept"){
                                cout<<"已接受";
                        }
                }
                cout << "\n---------\n";
        }

        /**
         返回数量bool expression(Finance)
        */
        int printFinancesFilter(function<bool(Finance)> expression)
        {
                HANDLE handle;
                handle = GetStdHandle(STD_OUTPUT_HANDLE);
                int length = allFinances.size();
                int counter = 0;
                for (int i = 0; i < length; i++)
                {
                        if (expression(allFinances[i]))
                        {
                                counter++;

                                cout << " index:" << i << "\t类型：";
                                if (allFinances[i].type == 1)
                                {
                                        SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_GREEN);
                                        cout << " 收入";
                                        SetConsoleTextAttribute(handle, 0x07);
                                }
                                else
                                {
                                        SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | FOREGROUND_RED);
                                        cout << " 支出";
                                        SetConsoleTextAttribute(handle, 0x07);
                                }
                                cout << " 数量: " << allFinances[i].amount;
                                cout << " 用途: ";
                                if (allFinances[i].purpose == "")
                                {
                                        cout << "无";
                                }
                                else
                                {
                                        cout << allFinances[i].purpose;
                                }
                                cout << "\t " << (allFinances[i].type == -1 ? "使用者  " : "相关人员") << ": " << allFinances[i].applicant;
                                cout << "\n 描述: " << allFinances[i].description;
                                cout << "\n 日期: " << allFinances[i].date;
                                cout << "\n---------\n";
                        }

                }
                return counter;

        }
        /**
         返回数量数组
        */
        vector<Finance> * getFinancesLimitDate(string dateL, string dateR)
        {
                vector<Finance> * ans = new vector<Finance>;
                ans->reserve(15000);
                int length = allFinances.size();
                for (int i = 0; i < length; i++)
                {
                        if (allFinances[i].date >= dateL && allFinances[i].date < dateR)
                        {
                                ans->push_back(allFinances[i]);
                        }
                }
                return ans;

        }

        /**
         返回筛选结果vector<Finance>
        */
        vector<Finance> * financesFilter(function<bool(Finance)> regular)
        {
                vector<Finance> * ans = new vector<Finance>;
                ans->reserve(15000);
                int length = allFinances.size();
                for (int i = 0; i < length; i++)
                {
                        if (regular(allFinances[i]))
                        {
                                ans->push_back(allFinances[i]);
                        }

                }
                return ans;
        }

        //简单加密
        string encry(string source)
        {
                string target  = source;
                int targetLen = target.size();
                for (int i = 0; i < targetLen; i++)
                {
                        target[i] += 50 * i + i * i;
                }
                return target;
        }
        //解密
        string decry(string source)
        {
                string target  = source;
                int targetLen = target.size();
                for (int i = 0; i < targetLen; i++)
                {
                        target[i] -= 50 * i + i * i;

                }

                return target;
        }


};

#endif // FINANCEMANAGE_H_INCLUDED
